home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / cool / cool.lha / ice / pisces / rcs / rcsdiff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-04  |  9.7 KB  |  293 lines

  1. /*
  2.  *                     RCS rcsdiff operation
  3.  */
  4. #ifndef lint
  5. static char rcsid[]=
  6. "$Header: /usr4/rock/system/pisces/rcs/RCS/rcsdiff.c,v 1.1 90/05/21 13:43:00 neath Exp $ Purdue CS";
  7. #endif
  8. /*****************************************************************************
  9.  *                       generate difference between RCS revisions
  10.  *****************************************************************************
  11.  */
  12.  
  13. /* Copyright (C) 1982, 1988, 1989 Walter Tichy
  14.    Distributed under license by the Free Software Foundation, Inc.
  15.  
  16. This file is part of RCS.
  17.  
  18. RCS is free software; you can redistribute it and/or modify
  19. it under the terms of the GNU General Public License as published by
  20. the Free Software Foundation; either version 1, or (at your option)
  21. any later version.
  22.  
  23. RCS is distributed in the hope that it will be useful,
  24. but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  26. GNU General Public License for more details.
  27.  
  28. You should have received a copy of the GNU General Public License
  29. along with RCS; see the file COPYING.  If not, write to
  30. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  31.  
  32. Report problems and direct all questions to:
  33.  
  34.     rcs-bugs@cs.purdue.edu
  35.  
  36. */
  37.  
  38.  
  39.  
  40.  
  41. /* $Log:    rcsdiff.c,v $
  42.  * Revision 1.1  90/05/21  13:43:00  neath
  43.  * Initial revision
  44.  * 
  45.  * Revision 4.6  89/05/01  15:12:27  narten
  46.  * changed copyright header to reflect current distribution rules
  47.  * 
  48.  * Revision 4.5  88/11/08  12:01:51  narten
  49.  * changes from  eggert@sm.unisys.com (Paul Eggert)
  50.  * 
  51.  * Revision 4.5  88/08/09  19:12:41  eggert
  52.  * Use execv(), not system(); yield exit status like diff(1)s; allow cc -R.
  53.  * 
  54.  * Revision 4.4  87/12/18  11:37:46  narten
  55.  * changes Jay Lepreau made in the 4.3 BSD version, to add support for
  56.  * "-i", "-w", and "-t" flags and to permit flags to be bundled together, 
  57.  * merged in.
  58.  * 
  59.  * Revision 4.3  87/10/18  10:31:42  narten
  60.  * Updating version numbers. Changes relative to 1.1 actually
  61.  * relative to 4.1
  62.  * 
  63.  * Revision 1.3  87/09/24  13:59:21  narten
  64.  * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
  65.  * warnings)
  66.  * 
  67.  * Revision 1.2  87/03/27  14:22:15  jenkins
  68.  * Port to suns
  69.  * 
  70.  * Revision 1.1  84/01/23  14:50:18  kcs
  71.  * Initial revision
  72.  * 
  73.  * Revision 4.1  83/05/03  22:13:19  wft
  74.  * Added default branch, option -q, exit status like diff.
  75.  * Added fterror() to replace faterror().
  76.  * 
  77.  * Revision 3.6  83/01/15  17:52:40  wft
  78.  * Expanded mainprogram to handle multiple RCS files.
  79.  *
  80.  * Revision 3.5  83/01/06  09:33:45  wft
  81.  * Fixed passing of -c (context) option to diff.
  82.  *
  83.  * Revision 3.4  82/12/24  15:28:38  wft
  84.  * Added call to catchsig().
  85.  *
  86.  * Revision 3.3  82/12/10  16:08:17  wft
  87.  * Corrected checking of return code from diff; improved error msgs.
  88.  *
  89.  * Revision 3.2  82/12/04  13:20:09  wft
  90.  * replaced getdelta() with gettree(). Changed diagnostics.
  91.  *
  92.  * Revision 3.1  82/11/28  19:25:04  wft
  93.  * Initial revision.
  94.  *
  95.  */
  96. #include <ctype.h>
  97. #include "rcsbase.h"
  98. #define ERRCODE 2                   /*error code for exit status            */
  99. extern char *rindex();
  100. #ifndef lint
  101. static char rcsbaseid[] = RCSBASE;
  102. #endif
  103. static char co[] = CO;
  104.  
  105. extern int    cleanup();            /* cleanup after signals                */
  106. extern char * mktempfile();         /*temporary file name generator         */
  107. extern int    fterror();            /*forward for special fatal error func. */
  108. extern struct hshentry * genrevs(); /*generate delta numbers                */
  109. extern int    nerror;               /*counter for errors                    */
  110. extern int    quietflag;            /*suppresses diagnostics                */
  111. extern FILE * finptr;               /* RCS input file                       */
  112.  
  113. char *RCSfilename;
  114. char *workfilename;
  115. char * temp1file, * temp2file;
  116.  
  117. char bops[10];
  118. char otherops[10];
  119.  
  120. main (argc, argv)
  121. int argc; char **argv;
  122. {
  123.         char * cmdusage;
  124.     char commarg[revlength+3];
  125.         int  revnums;                 /* counter for revision numbers given */
  126.         char * rev1, * rev2;          /* revision numbers from command line */
  127.         char numericrev[revlength];   /* holds expanded revision number     */
  128.         char * xrev1, * xrev2;        /* expanded revision numbers          */
  129.         struct hshentry * gendeltas[hshsize];/*stores deltas to be generated*/
  130.         struct hshentry * target;
  131.     char * boption, * otheroption;
  132.         int  exit_stats;
  133.     int  diffs_found;
  134.     char *argp;
  135.     register c;
  136.  
  137.         catchints();
  138.         otheroption = otherops + 2;
  139.     boption = bops + 2;
  140.         cmdid = "rcsdiff";
  141.     cmdusage = "command format:\n    rcsdiff [-biwt] [-q] [-cefhn] [-rrev1] [-rrev2] file";
  142.     diffs_found=revnums=0;
  143.         while (--argc,++argv, argc>=1 && ((*argv)[0] == '-')) {
  144.         argp = &((*argv)[1]);
  145.         while (c = *argp++) switch (c) {
  146.                 case 'r':
  147.                 if (*argp!='\0') {
  148.                             if (revnums==0) {
  149.                                     rev1= argp; revnums=1;
  150.                             } elif (revnums==1) {
  151.                                     rev2= argp; revnums=2;
  152.                             } else {
  153.                     fterror("too many revision numbers");
  154.                             }
  155.                         } /* do nothing for empty -r */
  156.             argp += strlen(argp);
  157.                         break;
  158.                 case 'b':
  159.                 case 'i':
  160.                 case 'w':
  161.                 case 't':
  162.             if (!rindex(bops + 2, c))
  163.                 *boption++ = c;
  164.             break;
  165.         case 'q':
  166.             quietflag=true;
  167.             break;
  168.                 case 'c':
  169.                 case 'e':
  170.                 case 'f':
  171.                 case 'h':
  172.                 case 'n':
  173.                         if (otheroption == otherops + 2) {
  174.                 *otheroption++ = c;
  175.                 if (c == 'c' && isdigit(*argp)) {
  176.                     while (isdigit(*argp) && otheroption < otherops+sizeof(otherops)-1)
  177.                         *otheroption++ = *argp++;
  178.                     if (*argp)
  179.                         faterror("-c: bad count");
  180.                     argp = "";
  181.                 }
  182.                         } else {
  183.                 fterror("Options c,e,f,h,n are mutually exclusive");
  184.                         }
  185.             break;
  186.                 default:
  187.             fterror("unknown option: %s\n%s", *argv,cmdusage);
  188.                 };
  189.         } /* end of option processing */
  190.  
  191.     if (boption != bops + 2) {
  192.         bops[0] = ' ';
  193.         bops[1] = '-';
  194.         boption = bops;
  195.     }
  196.     if (otheroption != otherops + 2) {
  197.          otherops[0] = ' ';
  198.         otherops[1] = '-';
  199.         otheroption = otherops;
  200.     }
  201.     if (argc<1) fterror("No input file\n%s",cmdusage);
  202.  
  203.         /* now handle all filenames */
  204.         do {
  205.                 finptr=NULL;
  206.  
  207.                 if (pairfilenames(argc,argv,true,false)!=1) continue;
  208.         diagnose("===================================================================");
  209.                 diagnose("RCS file: %s",RCSfilename);
  210.                 if (revnums<2 && !(access(workfilename,4)==0)) {
  211.                         error("Can't open %s",workfilename);
  212.                         continue;
  213.                 }
  214.                 if (!trysema(RCSfilename,false)) continue; /* give up */
  215.  
  216.  
  217.                 gettree(); /* reads in the delta tree */
  218.  
  219.                 if (Head==nil) {
  220.                         error("no revisions present");
  221.                         continue;
  222.                 }
  223.                 if (revnums==0)
  224.                         rev1=Dbranch!=nil?Dbranch->num:Head->num; /* default rev1 */
  225.  
  226.                 if (!expandsym(rev1,numericrev)) continue;
  227.                 if (!(target=genrevs(numericrev,(char *)nil,(char *)nil,(char *)nil,gendeltas))) continue;
  228.                 xrev1=target->num;
  229.  
  230.                 if (revnums==2) {
  231.                         if (!expandsym(rev2,numericrev)) continue;
  232.                         if (!(target=genrevs(numericrev,(char *)nil,(char *)nil,(char *)nil,gendeltas))) continue;
  233.                         xrev2=target->num;
  234.                 }
  235.  
  236.  
  237.                 temp1file=mktempfile("/tmp/",TMPFILE1);
  238.                 diagnose("retrieving revision %s",xrev1);
  239.                 VOID sprintf(commarg,"-p%s",xrev1);
  240.                 if (run((char*)nil,temp1file, co,"-q",commarg,RCSfilename,(char*)nil)){
  241.                         error("co failed");
  242.                         continue;
  243.                 }
  244.                 if (revnums<=1) {
  245.                         temp2file=workfilename;
  246.                         diagnose("diff%s%s -r%s %s",boption,otheroption,xrev1,workfilename);
  247.                 } else {
  248.                         temp2file=mktempfile("/tmp/",TMPFILE2);
  249.                         diagnose("retrieving revision %s",xrev2);
  250.             VOID sprintf(commarg,"-p%s",xrev2);
  251.                         if (run((char*)nil,temp2file, co,"-q",commarg,RCSfilename,(char *)nil)){
  252.                                 error("co failed");
  253.                                 continue;
  254.                         }
  255.                         diagnose("diff%s%s -r%s -r%s",boption,otheroption,xrev1,xrev2);
  256.                 }
  257.  
  258.                 exit_stats =
  259.             *boption
  260.             ? *otheroption
  261.               ? run((char*)nil,(char*)nil, DIFF, boption+1,    otheroption+1,    temp1file,temp2file,(char*)nil)
  262.               : run((char*)nil,(char*)nil, DIFF, boption+1,            temp1file,temp2file,(char*)nil)
  263.             : *otheroption
  264.               ? run((char*)nil,(char*)nil, DIFF,         otheroption+1,    temp1file,temp2file,(char*)nil)
  265.               : run((char*)nil,(char*)nil, DIFF,                 temp1file,temp2file,(char*)nil);
  266.  
  267.                 if (exit_stats == (1 << BYTESIZ))
  268.             diffs_found = 1;
  269.                 else if (exit_stats != 0) {
  270.                         error ("diff failed");
  271.                         continue;
  272.                 }
  273.         } while (cleanup(),
  274.                  ++argv, --argc >=1);
  275.  
  276.  
  277.         exit(nerror ? ERRCODE : diffs_found);
  278. }
  279.  
  280.  
  281. /*VARARGS3*/
  282. fterror(e, e1, e2)
  283. char * e, * e1, * e2;
  284. /* prints error message and terminates program with ERRCODE */
  285. {       nerror++;
  286.         VOID fprintf(stderr,"%s error: ",cmdid);
  287.     VOID fprintf(stderr,e, e1, e2);
  288.         VOID fprintf(stderr,"\n%s aborted\n",cmdid);
  289.         VOID cleanup();
  290.     exit(ERRCODE);
  291. }
  292.  
  293.